package com.atguigu.gmall.seckill.service.impl;

import com.atguigu.gmall.common.config.cache.aop.anntation.Cache;
import com.atguigu.gmall.common.constants.RedisConst;
import com.atguigu.gmall.common.util.DateUtil;
import com.atguigu.gmall.common.util.JsonUtil;
import com.atguigu.gmall.model.activity.SeckillGoods;
import com.atguigu.gmall.model.list.Goods;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.atguigu.gmall.seckill.service.SeckillGoodsService;
import com.atguigu.gmall.seckill.mapper.SeckillGoodsMapper;
import com.fasterxml.jackson.core.type.TypeReference;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.BoundHashOperations;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 *
 */
@Slf4j
@Service
public class SeckillGoodsServiceImpl extends ServiceImpl<SeckillGoodsMapper, SeckillGoods>
    implements SeckillGoodsService{
    @Autowired
    SeckillGoodsMapper seckillGoodsMapper;
    @Autowired
    StringRedisTemplate redisTemplate;
    //获得当前时间的秒杀商品
    //@Cache(CacheKey = RedisConst.SECKILL_GOODS_CACHE_PREFIX+"#{#currentTime}")
    @Override
    public List<SeckillGoods> getSecKillList() {
        //先去redis缓存中查
        Date date = new Date();
        String currentTime = DateUtil.formatDate(date);
        BoundHashOperations<String, String, String> seckillGoodsBound = redisTemplate.boundHashOps(RedisConst.SECKILL_GOODS_CACHE_PREFIX + currentTime);
        //判断这个大key是否存在了
        if (Boolean.TRUE.equals(seckillGoodsBound.persist())) {
            //有,去缓存中查
            List<String> stringList = seckillGoodsBound.values();
            List<SeckillGoods> seckillGoodsList = stringList.stream().map(s ->
                            JsonUtil.json2Obj(s, new TypeReference<SeckillGoods>() {
                            })
                    ).sorted(((o1, o2) -> o1.getStartTime().compareTo(o2.getStartTime())))
                    .collect(Collectors.toList());
            log.info("命中缓存:{}",seckillGoodsList);
            return seckillGoodsList;
        }else {
            //没有,就去查数据库
            log.info("未命中缓存,查库");
            List<SeckillGoods> secKillList = seckillGoodsMapper.getSecKillList(currentTime);
            //存到redis缓存中
            secKillList.forEach(item->{
                seckillGoodsBound.put(item.getSkuId().toString(),JsonUtil.obj2Json(item));
            });
            return secKillList;
        }

    }
    //获得指定时间的秒杀商品列表
    @Override
    public List<SeckillGoods> getFocusSecKillGoodsList(String plusDay) {
        return seckillGoodsMapper.getSecKillList(plusDay);
    }
    //获得当前时间skuId的秒杀商品详情
    @Override
    public SeckillGoods getSecKillDetails(Long skuId) {
        //直接从缓存中拿
        Date date = new Date();
        String currentTime = DateUtil.formatDate(date);
        BoundHashOperations<String, String, String> seckillGoodsBound = redisTemplate.boundHashOps(RedisConst.SECKILL_GOODS_CACHE_PREFIX + currentTime);
        String json = seckillGoodsBound.get(skuId.toString());
        SeckillGoods seckillGoods = JsonUtil.json2Obj(json, new TypeReference<SeckillGoods>() {
        });
        return seckillGoods;
    }

    @Override
    public void reduceStock(Long skuId) {
        seckillGoodsMapper.reduceStock(skuId);
    }
}




